package org.hackystat.sdsa.service.server;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;


/**
 * Provides access to the values stored in the sdsa.properties file, and provides
 * default values if the file is not found. 
 * 
 * @author Hongbing Kou
 */
public class ServerProperties {
  /** The sensorbase fully qualified host name, such as http://localhost:9876/sensorbase. */
  public static final String SENSORBASE_FULLHOST_KEY =  "sdsa.sensorbase.host";
    /** The sdsa hostname key. */
  public static final String HOSTNAME_KEY =        "sdsa.hostname";
  /** The SDSA service port key. */
  public static final String PORT_KEY =            "sdsa.port";
  /** The SDSA context root. */
  public static final String CONTEXT_ROOT_KEY =     "sdsa.context.root";

  /** The logging level key. */
  public static final String LOGGING_LEVEL_KEY =   "sdsa.logging.level";
  /** The XML directory key. */
  public static final String XML_DIR_KEY =         "sdsa.xml.dir";
 
  /** The sensorbase port key during testing. */
  public static final String TEST_PORT_KEY =       "sdsa.test.port";
  /** The test installation key. */
  public static final String TEST_INSTALL_KEY =    "sdsa.test.install";
  /** The test installation key. */
  public static final String TEST_HOSTNAME_KEY =    "sdsa.test.hostname";
  /** The test installation key. */
  public static final String TEST_SENSORBASE_FULLHOST_KEY = "sdsa.test.sensorbase.host";

  /** Where we store the properties. */
  private Properties properties; 
  
  /**
   * Creates a new ServerProperties instance. 
   * Prints an error to the console if problems occur on loading. 
   */
  public ServerProperties() {
    try {
      initializeProperties();
    }
    catch (Exception e) {
      System.out.println("Error initializing SDSA server properties.");
    }
  }
  
  /**
   * Reads in the properties in ~/.hackystat/sdsa/sdsa.properties 
   * if this file exists, and provides default values for all properties.
   * 
   * @throws Exception if errors occur.
   */
  private void initializeProperties () throws Exception {
    String userHome = System.getProperty("user.home");
    String userDir = System.getProperty("user.dir");
    String propFile = userHome + "/.hackystat/sdsa/sdsa.properties";
    this.properties = new Properties();
    // Set defaults
    properties.setProperty(SENSORBASE_FULLHOST_KEY, "http://localhost:9876/sensorbase/");
    properties.setProperty(HOSTNAME_KEY, "localhost");
    properties.setProperty(PORT_KEY, "9880");
    properties.setProperty(CONTEXT_ROOT_KEY, "sdsa");
    properties.setProperty(LOGGING_LEVEL_KEY, "INFO");
    properties.setProperty(XML_DIR_KEY, userDir + "/xml");
    properties.setProperty(TEST_PORT_KEY, "9980");
    properties.setProperty(TEST_HOSTNAME_KEY, "localhost");
    properties.setProperty(TEST_SENSORBASE_FULLHOST_KEY, "http://localhost:9976/sensorbase");
    properties.setProperty(TEST_INSTALL_KEY, "false");

    FileInputStream stream = null;
    try {
      stream = new FileInputStream(propFile);
      properties.load(stream);
      System.out.println("Loading SDSA properties from: " + propFile);
    }
    catch (IOException e) {
      System.out.println(propFile + " not found. Using default SDSA properties.");
    }
    finally {
      if (stream != null) {
        stream.close();
      }
    }
    // make sure that SENSORBASE_HOST always has a final slash.
    String sensorBaseHost = (String) properties.get(SENSORBASE_FULLHOST_KEY);
    if (!sensorBaseHost.endsWith("/")) {
      properties.put(SENSORBASE_FULLHOST_KEY, sensorBaseHost + "/");
    }    
    // Now add to System properties.
    Properties systemProperties = System.getProperties();
    systemProperties.putAll(properties);
    System.setProperties(systemProperties);
  }
  
  /**
   * Sets the following properties' values to their "test" equivalent.
   * <ul>
   * <li> HOSTNAME_KEY
   * <li> PORT_KEY
   * <li> SENSORBASE_FULLHOST_KEY
   * </ul>
   * Also sets TEST_INSTALL_KEY's value to "true".
   */
  public void setTestProperties() {
    properties.setProperty(HOSTNAME_KEY, properties.getProperty(TEST_HOSTNAME_KEY));
    properties.setProperty(PORT_KEY, properties.getProperty(TEST_PORT_KEY));
    properties.setProperty(SENSORBASE_FULLHOST_KEY, 
        properties.getProperty(TEST_SENSORBASE_FULLHOST_KEY));
    properties.setProperty(TEST_INSTALL_KEY, "true");
  }
  
  /**
   * Prints all of the SDSA settings to the logger.
   * @param server The SDSA server.   
   */
  public void echoProperties(Server server) {
    String cr = System.getProperty("line.separator"); 
    String eq = " = ";
    String pad = "                ";
    String propertyInfo = "SDSA Properties:" + cr +
      pad + SENSORBASE_FULLHOST_KEY + eq + get(SENSORBASE_FULLHOST_KEY) + cr +
      pad + HOSTNAME_KEY     + eq + get(HOSTNAME_KEY) + cr +
      pad + CONTEXT_ROOT_KEY  + eq + get(CONTEXT_ROOT_KEY) + cr +
      pad + LOGGING_LEVEL_KEY + eq + get(LOGGING_LEVEL_KEY) + cr +
      pad + PORT_KEY          + eq + get(PORT_KEY);
    server.getLogger().info(propertyInfo);
  }
  
  /**
   * Returns the value of the Server Property specified by the key.
   * @param key Should be one of the public static final strings in this class.
   * @return The value of the key, or null if not found.
   */
  public String get(String key) {
    return this.properties.getProperty(key);
  }
  
  /**
   * Returns the fully qualified host name, such as "http://localhost:9878/sdsa/".
   * 
   * @return The fully qualified host name.
   */
  public String getFullHost() {
    return "http://" + get(HOSTNAME_KEY) + ":" + get(PORT_KEY) + "/" + get(CONTEXT_ROOT_KEY) + "/";
  }
}